package org.jadelyre.core;

import org.jadelyre.core.codec.Packet;
import org.jadelyre.core.task.EntryQueue;
import org.jadelyre.core.worker.Worker;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;

public abstract class AbstractChannel implements Channel {

    private final JadeLyre jadeLyre;
    private final Worker<ByteBuffer> decodeWorker;
    private final Worker<Packet> handleWorker;
    private final Worker<Packet> sendWorker;
    private final ReadCompletionHandler readCompletionHandler;
    private final WriteCompletionHandler writeCompletionHandler;
    private final AsynchronousSocketChannel asynchronousSocketChannel;
    private NodeAddress remoteNodeAddress;
    private long lastReadTime;


    public AbstractChannel(JadeLyre jadeLyre, AsynchronousSocketChannel asynchronousSocketChannel
            , NodeAddress remoteNodeAddress) {
        this.jadeLyre = jadeLyre;
        this.remoteNodeAddress = remoteNodeAddress;
        this.decodeWorker = jadeLyre.getWorkerFactory().getDecodeWorker(this, new EntryQueue<ByteBuffer>());
        this.handleWorker = jadeLyre.getWorkerFactory().getHandleWorker(this, new EntryQueue<Packet>());
        this.sendWorker = jadeLyre.getWorkerFactory().getWriteWorker(this, new EntryQueue<Packet>());
        this.asynchronousSocketChannel = asynchronousSocketChannel;
        this.readCompletionHandler = new ReadCompletionHandler(asynchronousSocketChannel,ByteBuffer.allocate(jadeLyre.getJadeLyreConfig().getReadBufferSize()));
        this.writeCompletionHandler = new WriteCompletionHandler(asynchronousSocketChannel);
    }


    @Override
    public JadeLyre getJadeLyre() {
        return jadeLyre;
    }
    @Override
    public Worker<ByteBuffer> getDecodeWorker() {
        return decodeWorker;
    }

    @Override
    public Worker<Packet> getHandleWorker() {
        return handleWorker;
    }

    @Override
    public Worker<Packet> getSendWorker() {
        return sendWorker;
    }

    @Override
    public ReadCompletionHandler getReadCompletionHandler() {
        return readCompletionHandler;
    }
    @Override
    public WriteCompletionHandler getWriteCompletionHandler() {
        return writeCompletionHandler;
    }
    @Override
    public AsynchronousSocketChannel getAsynchronousSocketChannel() {
        return asynchronousSocketChannel;
    }

    @Override
    public NodeAddress getRemoteNodeAddress() {
        return remoteNodeAddress;
    }

    @Override
    public void close() {
        jadeLyre.getCloseWorker().work(this);
    }

    @Override
    public long getLastReadTime() {
        return lastReadTime;
    }

    @Override
    public void setLastReadTime(long lastReadTime) {
        this.lastReadTime = lastReadTime;
    }
}
